package com.sedric.base;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

import com.sedric.base.repository.BaseRepository;
import com.sv.utils.ReflectUtils;
import com.sv.utils.Xss;

@SuppressWarnings("unchecked")
@Xss
public class BaseDomain<T, U> implements Cloneable {

    private BaseRepository<T, U> repository;
    
    public int countByExample(U u) {
        try {
            return acquireBaseRepository().countByExample(u);
        }
        catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public int deleteByExample(U u) {
        try {
            return acquireBaseRepository().deleteByExample(u);
        }
        catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public int deleteByPrimaryKey() {
        try {
            return acquireBaseRepository().deleteByPrimaryKey((T) this);
        }
        catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public void insert() {
        try {
        	acquireBaseRepository().insert((T) this);
        }
        catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public void insertSelective() {
        try {
            acquireBaseRepository().insertSelective((T) this);
        }
        catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public List<T> selectByExample(U u) {
        List<T> list = null;
        try {
            list = acquireBaseRepository().selectByExample(u);
            List result = new ArrayList();
            for (T t : list) {
                Object obj = ReflectUtils.newInstance(this);
                ReflectUtils.copyProperties(t, obj);
                result.add(obj);
            }
            return result;
        }
        catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public T selectFirstByExample(U u) {
        List<T> list = null;
        try {
            list = acquireBaseRepository().selectByExample(u);
            if (null == list) {
                return null;
            }
            T t = list.get(0);
            Object obj = ReflectUtils.newInstance(this);
            ReflectUtils.copyProperties(t, this);

            return (T) obj;
        }
        catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public T selectByPrimaryKey() {
        try {
            T t = acquireBaseRepository().selectByPrimaryKey((T) this);
            if (null == t) {
                return null;
            }
            ReflectUtils.copyProperties(t, this);
            
            return (T) this;
        }
        catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     *  更新传入参数的字段
     *  
     * @param t 更新字段
     * @param u 条件参数
     * @return
     */
    public int updateByExampleSelective(U u) {
        try {
            return acquireBaseRepository().updateByExampleSelective((T)this,u);
        }
        catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     *  更新所有字段
     *  
     * @param t 更新字段
     * @param u 条件参数
     * @return
     */
    public int updateDateByExample(U u){
    	try {
            return acquireBaseRepository().updateByExampleSelective((T)this,u);
        }
        catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    
    /**
     * 根据主键更新传入的字段
     * @return
     */
    public int updateByPrimaryKeySelective() {
        try {
            return acquireBaseRepository()
                    .updateByPrimaryKeySelective((T) this);
        }
        catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    
    /**
     * 根据主键更新所有字段
     * @return
     */
    public int updateByPrimaryKey(){
    	try {
            return acquireBaseRepository()
                    .updateByPrimaryKeySelective((T) this);
        }
        catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public BaseRepository<T, U> getRepository() {
        return repository;
    }

    public void setRepository(BaseRepository<T, U> repository) {
        this.repository = repository;
    }

	public BaseRepository<T, U> acquireBaseRepository() {
        WebApplicationContext wac = ContextLoader
                .getCurrentWebApplicationContext();
        BaseRepository<T, U> r = wac.getBean("baseRepository",
                BaseRepository.class);

        return r;
    }
}
